package arg

import (
	"database/sql"
	"github.com/gurkankaymak/hocon"
	"gopkg.in/ini.v1"
	"db2s/conn"
	"db2s/global"
	"db2s/go-log/log"
	"db2s/outPut"
	"os"
	"reflect"
	"time"
)

var WLog *log.Logger

type ArgInput struct {
	InitCmd         InitCmdS
	AuthCmd         AuthCmdS
	MetaDataCmd     MetaDataCmdS
	RowsDataCmd     RowsDataCmdS
	TaskScheduleCmd TaskScheduleCmdS
	Mode            string //当前一级模式
	Config          string
	OptimizerSwitch OptimizerSwitch
	AuthCode        Auth
	Truncate        bool
	InitTask        bool
}

// FirstLevel1 二级参数
type FirstLevel1 struct {
	DSNs   hocon.Object
	Schema hocon.Object
	Rules  hocon.Object
	Struct hocon.Object
	Logs   hocon.Object
	Repair hocon.Object
	Result hocon.Object
}
type firstLevel struct {
	DSNs       hocon.Object `json:"DSNs"`
	DBPool     hocon.Object `json:"dbPool"`
	Schema     hocon.Object `json:"schema"`
	Rules      hocon.Object `json:"rules"`
	Limit      hocon.Object `json:"limit"`
	Inspection hocon.Object `json:"inspection"`
	Logs       hocon.Object `json:"logs"`
	Repair     hocon.Object `json:"repair"`
	Result     hocon.Object `json:"resultOut"`
}

type DSNsS struct {
	SrcDSN                 string `json:"srcDSN"`
	DstDSN                 string `json:"dstDSN"`
	SrcDBName              string `json:"src_dbname"`
	DestDBName             string `json:"dst_dbname"`
	SrcDrive               string `json:"src_drive"`
	SrcJdbc                string `json:"src_jdbc"`
	DestDrive              string `json:"dst_drive"`
	DestJdbc               string `json:"dst_jdbc"`
	CheckParameterSourceDB *sql.DB
	CheckParameterDestDB   *sql.DB
	Conn                   DBConn
	SourceConnText         conn.ConText
	TargetConnText         conn.ConText
}

type SchemaS struct {
	Tables    map[string][]string `json:"table"`
	TablesM   map[string]int
	MapTables map[string] /*库名+表名源端*/ string /*库名+表名对端*/
	//MapSchema           map[string] /*库名源端*/ string                      /*库名对端*/
	Global               map[string]string   `json:"global"`
	IgnoreTables         string              /*内部使用*/
	TableAccessCheck     bool                `json:"access"` /* 外部接收*/
	TableJoin            string              `json:"tableJoin"`
	IgnoreTableM         map[string][]string `json:"ignore"`
	CheckIndexObject     string              `json:"object"`
	LowerCaseTableNames  bool                `json:"lowerCase"`
	ForceIndex           map[string]string   `json:"forceIndex"`
	ForcePart            map[string]string   `json:"forcePart"`
	WhereSqlJ            map[string]string   `json:"whereSql"` /* 外部接收*/
	WhereSql             map[string]string   /*内部使用*/
	WhereAddJ            map[string]string   `json:"whereAdd"` /* 外部接收*/
	WhereAdd             map[string]string   /*内部使用*/
	TablePx              map[string]string   /*内部使用 无索引表的表并行查询度*/
	Partition            map[string]global.PartitionOptions
	EncryptionProperties map[string]global.EncryptionProperties /*表中多列的加解密函数*/
	ForceIndexSwitch     bool
	TableInput           []SchemaS /*内部使用*/
}

type DBPool struct {
	MaxOpenConn     int
	MaxIdleConn     int
	ConnMaxIdleTime time.Duration
	ConnMaxLifeTime time.Duration
}
type CpuLimit struct {
	Load string `json:"load"`
}
type MemLimit struct {
}
type NetLimit struct {
}
type DiskLimit struct {
}
type Limit struct {
	Switch bool      `json:"switch"`
	Cpu    CpuLimit  `json:"cpu"`
	Mem    MemLimit  `json:"mem"`
	Net    NetLimit  `json:"net"`
	Disk   DiskLimit `json:"disk"`
}
type CountRules struct {
	CheckMethod string            `json:"mod"`
	RowsMapRule map[string]string `json:"rule"`
	OutTime     time.Duration     `json:"endTime"`
	SqlMode     bool              `json:"sqlMode"`
	TimeOut     int               `json:"timeOut"`
	Breakpoint  bool              `json:"breakpoint"`
	SqlLogBin   bool              `json:"logBin"`
	Scn         string            `json:"scn"`
}
type RowsRules struct {
	DelayCheck  int               `json:"delay"`
	Options     string            `json:"options"`
	RowsMapRule map[string]string `json:"rule"`
	OutTime     time.Duration     `json:"endTime"`
	TimeOut     int               `json:"timeOut"`
	SqlMode     bool              `json:"sqlMode"`
	Breakpoint  bool              `json:"breakpoint"`
	SqlLogBin   bool              `json:"logBin"`
	Scn         string            `json:"scn"`
}
type SampleRules struct {
	CheckMethod  string            `json:"mod"`
	IgCount      bool              `json:"igCount"`
	RowsMapRule  map[string]string `json:"rule"`
	Proportion   int               `json:"spr"`
	TimeOut      int               `json:"timeOut"`
	SqlMode      bool              `json:"sqlMode"`
	Breakpoint   bool              `json:"breakpoint"`
	SqlLogBin    bool              `json:"logBin"`
	Scn          string            `json:"scn"`
	ActiveSwitch ActiveSwitch
}
type Xls struct {
	XlsFileName        string            `json:"fileName"`
	XlsSheetNameGather []string          `json:"sheetName"`
	TerminalSheetName  string            `json:"terminal"`
	XlsSafetySwitch    bool              `json:"safetySwitch"`
	XlsTailGather      map[string]string `json:"-"`
	XlsSheetStructMap  map[string]reflect.Type
}

type HotSqlOutPut struct {
	OutPutFay string `json:"fay"`
	FileFin   *os.File
	OutTime   time.Duration `json:"timeOut"`
}
type HotSqlInput struct {
	InputFay  string            `json:"fay"`
	FName     []string          `json:"name"`
	FExcision map[string]string `json:"excision"`
	FileFin   *os.File
	User      []string `json:"user"`
	Table     []string `json:"table"`
	QueryType string   `json:"queryType"`
	ExecTime  string   `json:"execTime"`
	StartTime string   `json:"startTime"`
	EndTime   string   `json:"endTime"`
}
type HotSql struct {
	Output       HotSqlOutPut `json:"output"`
	Input        HotSqlInput  `json:"input"`
	ActiveSwitch ActiveSwitch
}
type SyncS struct {
	Truncate           bool  `json:"truncate"`
	IgnoreColumnLength bool  `json:"igColumn"`
	FixRows            int64 `json:"fixRows"`
	SqlMode            bool  `json:"sqlMode"`
	Breakpoint         bool  `json:"breakpoint"`
	RowsLimit          int   `json:"rowsLimit"`
	BreakPointFin      *os.File
	SqlLogBin          bool   `json:"logBin"`
	Scn                string `json:"scn"`
	Analyze            bool   `json:"analyze"`
	IgError            []int  `json:"igErr"`
	TimeOut            []int  `json:"timeOut"`
	TimeOutNew         TimeOut
	Recover            bool `json:"recover"`
	WriteParameterOpt  bool `json:"paramOpt"`
}
type LogParameter struct {
}
type StructS struct {
	AlterObject       []string            `json:"alterObject"`
	AlterSubObject    map[string][]string `json:"alterSubObject"`
	SCheckMod         map[string]int
	AlterRule         map[string]map[string]string `json:"alterRule"`
	AlterMethod       string                       `json:"alterMethod"`
	SqlMode           bool                         `json:"sqlMode"`
	Breakpoint        bool                         `json:"breakpoint"`
	Drop              bool                         `json:"drop"`
	SqlLogBin         bool                         `json:"logBin"`
	Scn               string                       `json:"scn"`
	Case              bool                         `json:"case"`
	TimeOut           []int                        `json:"timeOut"`
	TimeOutNew        TimeOut
	WriteParameterOpt bool `json:"paramOpt"`
	ErrorSqlFile      string
	ErrorSqlFilePoint *os.File
	BreakPointFin     *os.File
}
type LoadS struct {
	Truncate       bool   `json:"truncate"`
	FixRows        int64  `json:"fixRows"`
	SqlMode        bool   `json:"sqlMode"`
	LoadMode       string `json:"mode"`
	IgColumn       bool   `json:"igColumn"`
	ColumnExcision string `json:"column"`
	RowsExcision   string `json:"rows"`
	SqlLogBin      bool   `json:"logBin"`
	LoadFilePath   string `json:"filePath"`
	LoadFileSafe   bool   `json:"safe"`
	LoadFileGzip   bool   `json:"gzip"`
	Breakpoint     bool   `json:"breakpoint"`
	BreakPointFin  *os.File
	ActiveSwitch   ActiveSwitch
	Scn            string `json:"scn"`
}

type RulesS struct {
	Mtc          int `json:"mtc"`
	Mcc          int `json:"mcc"`
	ChanRowCount int `json:"mrc"`
	QueueSize    int `json:"queue"`
	CheckMode    string
	Ratio        int
	Count        CountRules
	RowsR        RowsRules
	SampR        SampleRules
	HotSqlV      HotSql
	Struct       StructS
	Object       ObjectS
	Sync         SyncS
	Load         LoadS
	Task         TaskS
	Index        IndexS
	Partition    PartitionS
}

type CustomDuration time.Duration

type PartitionS struct {
	CheckMod      []string `json:"checkMod"`
	SCheckMod     map[string]int
	SalterSqlRule string `json:"alterRule"`
	Breakpoint    bool   `json:"breakpoint"`
	BreakPointFin *os.File
}

type IndexS struct {
	Breakpoint    bool `json:"breakpoint"`
	BreakPointFin *os.File
}

type logDefVal struct {
	FilePath string `json:"filePath"`
	File     string `json:"file"`
	Schedule string `json:"schedule"`
	Monitor  string `json:"monitor"`
	SendMsg  string `json:"sendMsg"`
	Error    string `json:"error"`
	Level    string `json:"level"`
}
type RepairS struct {
	DataFix         string `json:"fix"`
	FixTrxNum       int    `json:"trxNum"`
	FixFileName     string `json:"fileName"`
	BinlogLogging   bool   `json:"binlog"`
	FixFilePathBase string
	AbnormalResultF *os.File
	FixFileDeleteF  *os.File
	FixFileInsertF  *os.File
	FixFileDmlF     *os.File
	FixFileInsert   string
	FixFileDelete   string
	FixFileDml      string
	AbnormalResult  string
	FixFileAlterF   *os.File
	FixFileAlter    string
	FixFileWay      string `json:"way"`
}
type Result struct {
	GeneralResult   bool   `json:"generalResult"`
	Teletypewriter  string `json:"tty"`
	ResultOutFin    outPut.Result
	ResultOutMethod string
	XlsV            Xls `json:"xls"`
}
type ActiveSwitch struct {
	TableAccessPriInit  bool //表读写权限访问
	TableStructInit     bool //表结构初始化
	GlobalParameterInit bool //配置参数中包含全局参数的初始化
	TableIndexInit      bool //表索引初始化
	TableIndexFilter    bool //校验表是否过滤索引
	TableTruncate       bool //是否truncate table
	TableRecover        bool //是否对表做回收站操作
	PartitionInit       bool
}

type Excision struct {
	RowsSp   string `json:"rows"`
	ColumnSp string `json:"column"`
}
type File struct {
	Name      []string `json:"name"`
	ExcisionV Excision `json:"excision"`
}
type TimeLimit struct {
	StartTime string `json:"start"`
	EndTime   string `json:"end"`
}
type Filter struct {
	TimeLimitV TimeLimit `json:"time"`
	User       []string  `json:"user"`
	Type       []string  `json:"type"`
	Table      []string  `json:"table"`
	ExecTime   int64     `json:"execTime"`
}

type Input struct {
	FileV   File   `json:"file"`
	FilterV Filter `json:"filter"`
}
type Output struct {
}
type SlowLog struct {
	InputV  Input  `json:"input"`
	OutputV Output `json:"output"`
}
type Inspection struct {
	SlowLogV SlowLog `json:"slowLog"`
}
type DBConn struct {
	Source conn.ConEr
	Target conn.ConEr
}
type SecondaryLevel struct {
	DSnsV       DSNsS
	SchemaV     SchemaS
	TableObject []*InputTableAttributes
	DBPoolV     DBPool
	LimitV      Limit
	RulesV      RulesS
	InspectionV Inspection
	//LogV           LogS
	RepairV        RepairS
	ResultV        Result
	FunctionalMode string
	ActiveSwitchV  ActiveSwitch
}
type ConnPool struct {
	PoolMin int
	PoolMax int
}
type OptimizerSwitch struct {
	CpuOptimizer bool
	MemOptimizer bool
}
type Auth struct {
	Code              string //授权码
	CertificationFree bool   //取消授权
}
type Start struct {
	HttpPort int //http端口
	TcpPort  int //tcp端口
}
type Run struct {
	TaskId          string //taskId
	TaskName        string //task名字
	Config          string //配置文件信息
	OptimizerSwitch OptimizerSwitch
}
type ConfigParameter struct {
	FirstL1         firstLevel
	ArgInput        ArgInput
	SecondaryL      SecondaryLevel
	ConfFine        *ini.File
	Start           Start
	Run             Run
	Active          string
	Config          string //配置文件信息
	AuthCode        Auth   //机器授权码
	ActiveWay       string //运行方式
	OptimizerSwitch OptimizerSwitch
	Truncate        bool
	LogThreadSeq    int64
	vlog            string
	event           string
	BeginTime       time.Time
}

type schemaLevel struct {
	Object       string              `json:"object"`
	TableJoin    string              `json:"tableJoin"`
	LowerCase    bool                `json:"lowerCase"`
	IgnoreObject map[string][]string `json:"ignore"`
	GlobalObject string              `json:"global"`
}
type schemaModeCheck struct {
	FunctionalMode    []string       `json:"funcMode"`
	FuncPassParameter map[string]any `json:"funcPass"`
}
type (
	EncryptionProperties struct {
		LockFuncName   string   `json:"lock"`
		UnLockFuncName string   `json:"unlock"`
		ColumnSlice    []string `json:"column"`
		EsaColumnSeq   map[int]int
	}
	PartitionOptions struct {
		PartitionGather       []string `json:"pg"`
		IgnorePartitionGather []string `json:"ipg"`
	}
	TableSubOptions struct {
		ForceIndex         string               `json:"forceIndex"`
		ForcePart          string               `json:"forcePart"`
		WhereSql           string               `json:"whereSql"`
		PX                 string               `json:"px"`
		WhereAdd           string               `json:"whereAdd"`
		SecColumn          EncryptionProperties `json:"sec"`
		PartitionGather    PartitionOptions     `json:"partition"`
		SpecifiedPartition []string             `json:"pg"`
		IgnorePartition    []string             `json:"ipg"`
		InsertIgnore       string               `json:"ignore"`
		Role               string               `json:"role"`
	}
)
type InputTableAttributes struct {
	GroupSeq        int
	Schema          string
	Ignore          bool //忽略表属性
	MSchema         string
	Table           string
	MTable          string
	IndexObject     string
	TableJoin       string
	TableStatus     *int64 //表状态，-1 表示不存在，1表示存在
	TableAttributes TableSubOptions
	Static          global.StartPartConfigInputP
}

type globalSet struct {
	IgnoreTableM        map[string][]string `json:"ignore"`
	TableJoin           string              `json:"tableJoin"`
	LowerCaseTableNames bool                `json:"lowerCase"`
	ForceIndex          string              `json:"forceIndex"`
	ForcePart           string              `json:"forcePart"`
	WhereSql            string              `json:"whereSql"` /* 外部接收*/
	WhereAdd            string              `json:"whereAdd"` /* 外部接收*/
	CheckIndexObject    string              `json:"object"`
}

var rc ConfigParameter

type (
	EsaTableOptions struct {
		Columns []string `json:"column"`
		Unlock  string   `json:"unlock"`
		Lock    string   `json:"lock"`
	}
	ObjectSubOptions struct {
		ForceIndex      string           `json:"forceIndex"`
		ForcePart       string           `json:"forcePart"`
		WhereSql        string           `json:"whereSql"`
		PX              string           `json:"px"`
		WhereAdd        string           `json:"whereAdd"`
		SecColumn       EsaTableOptions  `json:"sec"`
		PartitionGather PartitionOptions `json:"partition"`
		Role            string           `json:"role"`
	}

	ObjectAttributes struct {
		GroupSeq        int
		Object          TableObject
		Ignore          bool //忽略表属性
		TableJoin       string
		TableStatus     *int64 //表状态，-1 表示不存在，1表示存在
		TableAttributes ObjectSubOptions
	}
)
